package cn.turboinfo.dongying.api.provider.admin.impl.cms;

import cn.turboinfo.dongying.api.domain.admin.service.cms.CmsArticleService;
import cn.turboinfo.dongying.api.entity.admin.exception.cms.CmsArticleException;
import cn.turboinfo.dongying.api.entity.admin.pojo.cms.CmsArticle;
import cn.turboinfo.dongying.api.entity.admin.pojo.cms.CmsArticleCreator;
import cn.turboinfo.dongying.api.entity.admin.pojo.cms.CmsArticleUpdater;
import cn.turboinfo.dongying.api.provider.admin.repository.database.cms.CmsArticleDAO;
import cn.turboinfo.dongying.api.provider.admin.repository.database.cms.CmsArticlePO;
import net.sunshow.toolkit.core.qbean.api.request.QPage;
import net.sunshow.toolkit.core.qbean.api.request.QRequest;
import net.sunshow.toolkit.core.qbean.api.response.QResponse;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanCreatorHelper;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanUpdaterHelper;
import net.sunshow.toolkit.core.qbean.helper.service.impl.AbstractQServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

@Service
public class CmsCmsArticleServiceImpl extends AbstractQServiceImpl<CmsArticle> implements CmsArticleService {
    private CmsArticleDAO cmsArticleDAO;

    @Override
    public Optional<CmsArticle> getById(Long id) {
        return cmsArticleDAO.findById(id).map(this::convertQBean);
    }

    @Override
    public CmsArticle getByIdEnsure(Long id) {
        return getById(id).orElseThrow(this.getExceptionSupplier("未找到数据, id=" + id, null));
    }

    @Override
    public List<CmsArticle> findByIdCollection(Collection<Long> idCollection) {
        return convertStreamQBeanToList(cmsArticleDAO.findByIdInOrderByIdDesc(idCollection).stream());
    }

    @Override
    @Transactional
    public CmsArticle save(CmsArticleCreator creator) throws CmsArticleException {
        CmsArticlePO articlePO = new CmsArticlePO();

        QBeanCreatorHelper.copyCreatorField(articlePO, creator);

        return convertQBean(cmsArticleDAO.save(articlePO));
    }

    @Override
    @Transactional
    public CmsArticle update(CmsArticleUpdater updater) throws CmsArticleException {
        CmsArticlePO articlePO = getEntityWithNullCheckForUpdate(updater.getUpdateId(), cmsArticleDAO);

        QBeanUpdaterHelper.copyUpdaterField(articlePO, updater);

        return convertQBean(articlePO);
    }

    @Override
    public QResponse<CmsArticle> findAll(QRequest request, QPage requestPage) {
        return convertQResponse(findAllInternal(request, requestPage));
    }

    private Page<CmsArticlePO> findAllInternal(QRequest request, QPage requestPage) {
        return cmsArticleDAO.findAll(convertSpecification(request), convertPageable(requestPage));
    }

    @Override
    public List<CmsArticle> findArticleByCategory(Long categoryId) {
        return convertStreamQBeanToList(cmsArticleDAO.findAllByCategoryId(categoryId).stream());
    }

    @Override
    public List<CmsArticle> findAllArticleByCategory(List<Long> categoryCollection) {
        return convertStreamQBeanToList(cmsArticleDAO.findAllByCategoryIdIn(categoryCollection).stream());
    }

    @Override
    @Transactional
    public void deleteById(Long id) throws CmsArticleException {
        CmsArticlePO articlePO = getEntityWithNullCheckForUpdate(id, cmsArticleDAO);
        articlePO.setDeletedTime(System.currentTimeMillis());
    }

    @Override
    protected Supplier<? extends RuntimeException> getExceptionSupplier(String message,
                                                                        Throwable cause) {
        return () -> new CmsArticleException(message, cause);
    }

    @Autowired
    public void setArticleDAO(CmsArticleDAO articleDAO) {
        this.cmsArticleDAO = articleDAO;
    }
}
